package com.android.fragmentdemo.definervlayoutmanager
import android.graphics.PointF
import android.util.Log
import android.view.View
import androidx.recyclerview.widget.RecyclerView

class LooperLayoutManager3 : RecyclerView.LayoutManager(), RecyclerView.SmoothScroller.ScrollVectorProvider {

    //private val mActivity = activity

    override fun onAttachedToWindow(view: RecyclerView?) {
        super.onAttachedToWindow(view)
        //ScreenUtil.adapterScreen(mActivity, mActivity.resources.displayMetrics.ydpi, false)
    }

    override fun onDetachedFromWindow(view: RecyclerView?, recycler: RecyclerView.Recycler?) {
        super.onDetachedFromWindow(view, recycler)
        //ScreenUtil.resetScreen(mActivity)
    }

    override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
        return RecyclerView.LayoutParams(
            RecyclerView.LayoutParams.WRAP_CONTENT,
            RecyclerView.LayoutParams.WRAP_CONTENT
        )
    }

    override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
        return if (childCount == 0) {
            null
        } else {
            val firstChildPos = getPosition(getChildAt(0)!!)
            val direction = if (targetPosition < firstChildPos) -1 else 1
            return PointF(0F, direction.toFloat())
        }
    }

    override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
        //分离并且回收当前附加的所有View
        detachAndScrapAttachedViews(recycler)
        if (itemCount == 0) {
            return
        }
        //竖向绘制子View,则需要知道 Y轴的偏移量
        var offsetY = 0
        //绘制并添加view
        for (i in 0 until itemCount) {
            val view = recycler.getViewForPosition(i)
            addView(view)
            measureChildWithMargins(view, 0, 0)
            val viewWidth = getDecoratedMeasuredWidth(view)
            val viewHeight = getDecoratedMeasuredHeight(view)
            layoutDecorated(view, 0, offsetY, viewWidth, offsetY + viewHeight)
            offsetY += viewHeight
            if (offsetY > height) {
                break
            }
        }
    }

    override fun canScrollVertically() = true


    override fun scrollVerticallyBy(
        dy: Int,
        recycler: RecyclerView.Recycler,
        state: RecyclerView.State?
    ): Int {
        recycleViews(dy, recycler)
        fill(dy, recycler)
        offsetChildrenVertical(dy * -1)
        Log.d(TAG,"dy:${dy}")
        return dy
    }

    private fun fill(dy: Int, recycler: RecyclerView.Recycler) {
        if (dy > 0) {
            //上滑
            while (true) {
                //得到当前已添加（可见）的最后一个子View
                val lastVisibleView = getChildAt(childCount - 1) ?: break

                //如果滑动过后，View还是未完全显示出来就 不进行绘制下一个View
                //Log.d(TAG, "lastVisibleView.top:${lastVisibleView.top},dy:${dy}")
                if (lastVisibleView.bottom - dy > height) {
                    break
                }

                //得到View对应的位置
                val layoutPosition = getPosition(lastVisibleView)
                /**
                 * 例如要显示20个View，当前可见的最后一个View就是第20个，那么下一个要显示的就是第一个
                 * 如果当前显示的View不是第20个，那么就显示下一个，如当前显示的是第15个View，那么下一个显示第16个
                 * 注意区分 childCount 与 itemCount
                 */
                //Log.d(TAG, "layoutPosition:${layoutPosition}")
                val nextView : View = if (layoutPosition == itemCount - 1) {
                    recycler.getViewForPosition(0)
                } else {
                    recycler.getViewForPosition(layoutPosition + 1)
                }
                addView(nextView)
                measureChildWithMargins(nextView, 0, 0)
                val viewWidth = getDecoratedMeasuredWidth(nextView)
                val viewHeight = getDecoratedMeasuredHeight(nextView)
                val offsetY = lastVisibleView.bottom
                layoutDecorated(nextView, 0, offsetY, viewWidth, offsetY + viewHeight)
            }
        } else {
            //下滑
            while (true) {
                val firstVisibleView = getChildAt(0) ?: break
                //如果滑动过后，View还是未完全显示出来就 不进行绘制下一个View
                //firstVisibleView.top + dy--经常闪屏
                //firstVisibleView.bottom + dy--轻微闪屏
                //firstVisibleView.bottom--不会闪屏
                if (firstVisibleView.bottom < 0) {
                    break
                }
                val layoutPosition = getPosition(firstVisibleView)
                //Log.d(TAG, "layoutPosition:${layoutPosition}")
                /**
                 * 如果当前第一个可见View为第0个，则左侧显示第20个View 如果不是，下一个就显示前一个
                 */
                val nextView = if (layoutPosition == 0) {
                    recycler.getViewForPosition(itemCount - 1)
                } else {
                    recycler.getViewForPosition(layoutPosition - 1)
                }
                addView(nextView, 0)
                measureChildWithMargins(nextView, 0, 0)
                val viewWidth = getDecoratedMeasuredWidth(nextView)
                val viewHeight = getDecoratedMeasuredHeight(nextView)
                val offsetY = firstVisibleView.top
                layoutDecorated(nextView, 0,-viewHeight + offsetY, viewWidth, offsetY)
            }
        }
    }

    private fun recycleViews(dy: Int, recycler: RecyclerView.Recycler) {
        for (i in 0 until itemCount) {
            val childView = getChildAt(i) ?: continue
            if (dy > 0) {
                //上滑
                //移除并回收 原点 上侧的子View
                if (childView.bottom - dy < 0) {
                    removeAndRecycleViewAt(i, recycler)
                    //Log.d(TAG, "childView.bottom - dy < 0")
                }
            } else {
                //下滑
                //移除并回收 下侧即RecyclerView宽度之以外的子View
                //childView.top + dy
                //childView.top
                if (childView.top > height) {
                    //Log.d(TAG, "childView.top + dy > height")
                    removeAndRecycleViewAt(i, recycler)
                }
            }
        }
    }

    companion object {
        const val TAG = "LooperLayoutManager3"
    }
}